import numpy as np  # 引入numpy库  np简化别名

if __name__ == "__main__":


    # 查看当前np对应版本号
    print(np.__version__)
    lst = [1,2,3]  # python 自身就带有列表的概念
    """"在这样的基础上为什么还要封装 numpy 的 向量 相应的对象 ？ 
    难道不吭可以直接使用python本身的列表来表示向量？
    除了和面向对象相关，我们把它封装成一个专门的向量对象
    可以非常方便的定义属于这个对象的相应的方法
    还有非常重要的： python的列表中 本身里面是可以存储任意类型的数据的
    即使这些数据类型不一致
    """
    # 比如：
    lst[0] = "linear algebra"
    print(lst)
    """python 列表的本质 其实 是一个 动态的数组
    对于数组这种数据结构 ， 它本质是为了存储数据 
    而并不是为了数学计算 
    而 numpy 里的向量 只能存储一种数据类型
    我们基于numpy对象进行运算速度是非常快的"""


    ## 声明一些numpy向量
    vec = np.array([1,2,3])  # 传入python列表
    print(vec)

    ## 可更改的向量类
    vec[0] = 666
    print(vec)
    vec[0] = 1


    ## 创建零向量
    print(np.zeros(6))  ## 默认创建向量里的数据类型是浮点型  [0. 0. 0. 0. 0. 0.]
    ## one向量
    print(np.ones(6))
    ## 统一向量
    print(np.full(6 , 666))


    ## 向量的基本属性 ：
    ## 向量有多少元素
    print( "size = ", vec.size)
    ## np中重载的 len 函数
    print(len(vec))
    print(vec[0]) # 第一个元素
    print(vec[-1]) # 最后一个元素
    print(vec[0:2]) # 切片方式查看前两位
    """也就是说把原向量 前两个维度抽离出来 组成了一个新的二维向量"""
    print(type(vec[0:2])) # <class 'numpy.ndarray'>

    ## np.array 的基本运算
    vec2 = np.array([3,5,6])
    vec2[0] = 4
    ## 向量相加
    print("{} + {} = {}".format(vec , vec2 , vec + vec2))
    ## 相减
    print("{} - {} = {}".format(vec , vec2 , vec - vec2))
    ## 数量乘法
    print("{} * {} = {}".format(2 , vec2 , 2 *  vec2))
    ## 数量乘法 - 标量 右侧
    print("{} * {} = {}".format(vec2 , 2 , vec2 *  2))
    ## 向量相乘 - element-wise multiplication  两个向量分量逐个相乘得到的向量结果 （这样的乘法是没有实际数学意义）
    print("{} * {} = {}".format(vec , vec2 , vec *  vec2))
    ## 点乘
    print("{}.dot({}) = {}".format(vec , vec2 , vec.dot(vec2)))
    ## 求模   np.linalg -> linear algebra 子模块下 调用方法
    print(np.linalg.norm(vec))
    ## 向量的规范化 / 归一化 / 单位向量
    print(vec / np.linalg.norm(vec)); """"将vec这个向量中的每一个元素都除以这个向量的模 ， 得到单位向量"""
    ## 求单位向量的模 1
    print(np.linalg.norm(vec / np.linalg.norm(vec)))

    """由于numpy中没有封装求一个向量的单位向量方法
    所以在做除法的时候 如果 除数 是0  ， 这种情况 需要自行处理"""
    try:
        zero3 = np.zeros(3)
        zero3 / np.linalg.norm(zero3)
    except RuntimeWarning:
        print("除数不能为向量~")








